package main.com.service;

import com.alibaba.fastjson.JSONObject;
import main.com.pojo.Text;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.histogram.ParsedHistogram;
import org.elasticsearch.search.aggregations.bucket.range.ParsedRange;
import org.elasticsearch.search.aggregations.bucket.range.Range;
import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedAvg;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ElasticService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private TextService textService;

    private String indexName = "text";

    //创建索引,映射配置
    public boolean createIndex() throws Exception {
        CreateIndexRequest request = new CreateIndexRequest(indexName);
        request.settings(Settings.builder()
                .put("index.number_of_shards", 3)
                .put("index.number_of_replicas", 2));


        Map<String, Object> id = new HashMap<>();
        id.put("type", "keyword");
        Map<String, Object> title = new HashMap<>();
        title.put("type", "keyword");
        Map<String, Object> subTitle = new HashMap<>();
        subTitle.put("type", "keyword");
        Map<String, Object> price = new HashMap<>();
        price.put("type", "keyword");

        Map<String, Object> properties = new HashMap<>();
        properties.put("id", id);
        properties.put("title", title);
        properties.put("subTitle", subTitle);
        properties.put("price", price);

        Map<String, Object> mapping = new HashMap<>();
        mapping.put("properties", properties);

        request.mapping(mapping);

        CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        return createIndexResponse.isAcknowledged();
    }

    //加入所有数据

    public void addAll() throws Exception{
        List<Text> select = textService.select();
        for (Text t: select) {
            boolean b = saveOrUpdate(t);
        }

    }

    //新增数据(自定义id)，修改一样
    public boolean saveOrUpdate(Text text) throws Exception {
        IndexRequest request = new IndexRequest(indexName);
        request.id(text.getId().toString());
        request.source(JSONObject.toJSONString(text), XContentType.JSON);

        IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
            System.out.println("created OK");
            return true;
        }
        if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
            System.out.println("update OK");
            return true;
        }
        return false;

    }

    //删除数据
    public boolean deleteById(Integer id) throws Exception {
        DeleteRequest request = new DeleteRequest(indexName, id.toString());
        DeleteResponse deleteResponse = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        if (deleteResponse.getResult() == DocWriteResponse.Result.NOT_FOUND) {
            System.out.println("NOT_FOUND");
            return false;
        }
        return true;
    }


    //多字段查询
    public List<Text> queryMultiMatch(String t) throws Exception {
        MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(t, "title", "subTitle");
       /* HighlightBuilder highlightBuilder = new HighlightBuilder(); //生成高亮查询器
        highlightBuilder.field("title");      //高亮查询字段
        highlightBuilder.field("subTitle");    //高亮查询字段
        highlightBuilder.requireFieldMatch(false);     //如果要多个字段高亮,这项要为false
        highlightBuilder.preTags("<span style=\"color:red\">");   //高亮设置
        highlightBuilder.postTags("</span>");*/
        return processHits(queryBuilder);
    }

    //封装查询对象
    private List<Text> processHits(QueryBuilder queryBuilder) throws Exception {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        System.out.println("searchSourceBuilder==========>" + searchSourceBuilder);
        SearchRequest searchRequest = new SearchRequest(indexName);
        searchRequest.source(searchSourceBuilder);
        //
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);


        SearchHits hits = searchResponse.getHits();
        System.out.println("总数 = " + hits.getTotalHits());
        SearchHit[] searchHits = hits.getHits();
        List<Text> texts = new ArrayList<>();
        for (SearchHit hit : searchHits) {
            //得到的是json字符串
            String sourceAsString = hit.getSourceAsString();
            //将字符串转化对象
            Text t = JSONObject.parseObject(sourceAsString, Text.class);
            texts.add(t);
        }
        return texts;
    }
}